package com.ziyun.pop.modules.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pay.api.UmfpayService;
import com.pay.model.PayRecallResult;
import com.pay.model.pay.QueryPayParam;
import com.pay.model.pay.QueryPayResult;
import com.pay.model.pay.WebPayParam;
import com.service.common.constant.AppType;
import com.service.common.constant.OrderStatusChangeEvent;
import com.service.common.protocol.BaseResult;
import com.service.common.utils.BeanMapUtil;
import com.service.pay.conf.CallbackConfig;
import com.service.pay.conf.UmfPayConfig;
import com.service.pay.constants.PayTradeStateCode;
import com.service.pay.exception.PayException;
import com.utility.*;
import com.ziyun.pop.common.e.DeleteEnum;
import com.ziyun.pop.common.e.order.*;
import com.ziyun.pop.common.e.production.FinanceStatusEnum;
import com.ziyun.pop.common.e.production.OrderProductionStatusEnum;
import com.ziyun.pop.common.pay.*;
import com.ziyun.pop.common.utils.ErpOrderUtils;
import com.ziyun.pop.common.utils.JsonUtils;
import com.ziyun.pop.modules.erpOrderLog.service.ErpOrderLogService;
import com.ziyun.pop.modules.order.dao.ErpOrderInfoDao;
import com.ziyun.pop.modules.order.dto.OrderDiscountDto;
import com.ziyun.pop.modules.order.entity.*;
import com.ziyun.pop.modules.order.service.*;
import com.ziyun.pop.modules.order.vo.FactoryOrderItemVo;
import com.ziyun.pop.modules.order.vo.FactoryOrderVo;
import com.ziyun.pop.modules.order.vo.PaperInfoVO;
import com.ziyun.pop.modules.order.vo.QuoteProductInfoParamVo;
import com.ziyun.pop.modules.orderRemarks.service.OrderRemarksService;
import com.ziyun.pop.modules.production.entity.ErpOrderProductionEntity;
import com.ziyun.pop.modules.production.service.ErpOrderItemService;
import com.ziyun.pop.modules.production.service.ErpOrderProductionService;
import com.ziyun.pop.modules.supp.entity.SellerInfoEntity;
import com.ziyun.pop.modules.supp.service.SellerInfoService;
import com.ziyun.pop.modules.userPayment.service.UserPaymentService;
import com.ziyun.pop.modules.userPaymentBill.entity.UserPaymentBillEntity;
import com.ziyun.pop.modules.userPaymentBill.service.UserPaymentBillService;
import io.renren.common.exception.RRException;
import io.renren.common.exception.ResultCode;
import io.renren.common.utils.DateUtils;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.R;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.*;

/**
 * 工厂订单实现类
 *
 * @author gaosheng
 * @date 2018-09-26 17:02
 */
@Service("factoryOrderService")
public class FactoryOrderServiceImpl extends ServiceImpl<ErpOrderInfoDao, OrderInfoEntity> implements FactoryOrderService {
    private static Logger _log = LoggerFactory.getLogger(FactoryOrderServiceImpl.class);

    @Autowired
    private OrderItemService orderItemService;
    @Autowired
    private ErpOrderItemService erpOrderItemService;
    @Autowired
    private ErpOrderService erpOrderService;
    @Autowired
    private ErpOrderAllotRelevanceService erpOrderAllotRelevanceService;
    @Autowired
    private ErpOrderProductionService erpOrderProductionService;
    @Autowired
    private UserPaymentService userPaymentService;
    @Autowired
    private UserPaymentBillService userPaymentBillService;
    @Autowired
    private OrderInfoService orderInfoService;
    @Autowired
    private UmfpayService umfPayService;
    @Autowired
    private CallbackConfig callbackConfig;
    @Autowired
    private UmfPayConfig umfPayConfig;
    @Autowired
    private OrderLogService orderLogService;
    @Autowired
    private OrderPaymentService paymentService;
    @Autowired
    private SellerInfoService sellerInfoService;
    @Autowired
    private OrderTaxService orderTaxService;
    @Autowired
    private ErpOrderLogService erpOrderLogService;
    @Autowired
    private OrderRemarksService orderRemarksService;

    @Value("${pay.mfSyncCallbackuUrl}")
    private String mfSyncCallbackuUrl;

    @Override
    public R queryPageSellerFactoryOrderList(Map<String, Object> params) {
        int totalCount = this.baseMapper.countSellerFactoryOrder(params);
        int current = Integer.valueOf((String) params.get("page"));
        int size = Integer.valueOf((String) params.get("limit"));
        params.put("offset", (current - 1) * size);
        params.put("limit", size);
        List<FactoryOrderVo> list = this.baseMapper.queryPageSellerFactoryOrderList(params);

        Map<String, List> mapEnum = new HashMap<>();
        mapEnum.put("payStatusEnum", JsonUtils.enumToList(PayStatusEnum.class));
        mapEnum.put("productionStatusEnum", JsonUtils.enumToList(ProductionStatusEnum.class));
        mapEnum.put("orderInfoStatusEnum", JsonUtils.enumToList(OrderInfoStatusEnum.class));

        R r = R.ok();
        r.put("page", new PageUtils(list, totalCount, size, current));
        r.put("userData", mapEnum);
        return r;

    }

    @Override
    public R queryPageBuyerFactoryOrderList(Map<String, Object> params) {
        int totalCount = this.baseMapper.countBuyerFactoryOrder(params);
        int current = Integer.valueOf((String) params.get("page"));
        int size = Integer.valueOf((String) params.get("limit"));
        params.put("offset", (current - 1) * size);
        params.put("limit", size);
        List<FactoryOrderVo> list = this.baseMapper.queryPageBuyerFactoryOrderList(params);

        // 存放枚举类到userdata
        Map<String, List> mapEnum = new HashMap<>();
        mapEnum.put("orderInfoStatusEnum", JsonUtils.enumToList(OrderInfoStatusEnum.class));
        mapEnum.put("payStatusEnum", JsonUtils.enumToList(PayStatusEnum.class));
        mapEnum.put("payTypeEnum", JsonUtils.enumToList(PayTypeEnum.class));
        mapEnum.put("productionStatusEnum", JsonUtils.enumToList(ProductionStatusEnum.class));

        R r = R.ok();
        r.put("page", new PageUtils(list, totalCount, size, current));
        r.put("userData", mapEnum);
        return r;
    }

    @Override
    public R orderInfo(String orderId) {
        /* 订单信息 */
        FactoryOrderVo factoryOrderVo = this.baseMapper.selectFactoryOrdeVoByOrderId(orderId);
        /* 商品集合 */
        List<FactoryOrderItemVo> orderItemList = orderItemService.selectFactoryOrderItemByOrderId(Long.valueOf(orderId));
        /* 发票信息 */
        OrderTaxEntity orderTax = orderTaxService.getById(orderId);
        /* 支付信息 */
        Long parentOrderId = factoryOrderVo.getParentOrderId();
        String relId = parentOrderId == null ? orderId.toString() : parentOrderId.toString();
        List<UserPaymentEntity> userPaymentEntities = userPaymentService.queryOrderPaymentInfo(relId);

        return R.ok().put("factoryOrder", factoryOrderVo)
                .put("orderItemList", orderItemList)
                .put("orderTax", orderTax)
                .put("userPaymentList", userPaymentEntities);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R audit(Integer itemId) {
        OrderItemEntity orderItem = orderItemService.getById(itemId);
        Map<String, Object> updateMap = new HashMap<>();
        updateMap.put("approvalStatus", ApprovalStatusEnum.AUDITED.toInt());
        orderItemService.updateByMap(updateMap, itemId);

        // 查询工厂订单商品是否都已审核
        Long orderId = orderItem.getOrderId();
        int count = orderItemService.count(new QueryWrapper<OrderItemEntity>()
                .eq("order_id", orderId)
                .eq("approval_status", ApprovalStatusEnum.UN_AUDIT.toInt())
        );
        if (count == 0) {
            updateMap.clear();
            updateMap.put("payStatus", PayStatusEnum.NOT_PAY_0.toCode());
            this.baseMapper.updateByMap(orderId.toString(), updateMap);
        }

        return R.ok();
    }

    @Override
    public R orderItemInfo(String orderId) {
        R result = R.ok();

        List<OrderItemEntity> orderItemEntities = orderItemService.selectByOrderId(Long.valueOf(orderId));
        // 默认一条商品展示信息
        OrderItemEntity orderItem = orderItemEntities.get(0);
        // 总价
        BigDecimal price = orderItem.getPrice();
        // 成本价
        BigDecimal sharePrice = orderItem.getSharePrice();
        if (sharePrice == null) {
            sharePrice = BigDecimal.ZERO;
        }
        // 利润
        BigDecimal subtract = price.subtract(sharePrice);
        // 规格参数
        String addon = orderItem.getAddon();
        if (StringUtils.isNotBlank(addon)) {
            List<QuoteProductInfoParamVo> quoteProductInfoList = JsonUtils.string2Collection(addon, ArrayList.class, QuoteProductInfoParamVo.class);
            result.put("quoteProductInfoList", quoteProductInfoList);
        }
        // 报价计算过程
        String calculationPriceProcess = orderItem.getCalculationPriceProcess();
        if (StringUtils.isNotBlank(calculationPriceProcess)) {
            PaperInfoWrapper paperInfoWrapper = JsonUtils.string2Object(calculationPriceProcess, PaperInfoWrapper.class);
            List<PaperInfoVO> paperInfoList = paperInfoWrapper.getPaperInfoVOs();
            BigDecimal totalCraftPrice = BigDecimal.ZERO;
            BigDecimal totalPrintPrice = BigDecimal.ZERO;
            Map<String, BigDecimal> attributeValueTypeMap = new HashMap<>();
            for (PaperInfoVO info : paperInfoList) {
                totalCraftPrice = totalCraftPrice.add(BigDecimal.valueOf(info.getCraftPrice()));
                totalPrintPrice = totalPrintPrice.add(BigDecimal.valueOf(info.getPrintPrice())).add(BigDecimal.valueOf(info.getPaperPrice()));
                Map<AttributeValueType, Double> craftPriceMap = info.getCraftPriceMap();
                if (craftPriceMap != null && craftPriceMap.size() > 0) {
                    for (Map.Entry<AttributeValueType, Double> entry : craftPriceMap.entrySet()) {
                        AttributeValueType key = entry.getKey();
                        Double value = entry.getValue();
                        if (attributeValueTypeMap.containsKey(key.getName())) {
                            BigDecimal bd = attributeValueTypeMap.get(key.getName());
                            bd = bd.add(BigDecimal.valueOf(value));
                            attributeValueTypeMap.put(key.getName(), bd);
                        } else {
                            attributeValueTypeMap.put(key.getName(), BigDecimal.valueOf(value));
                        }
                    }
                }
            }
            if (attributeValueTypeMap.size() > 0) {
                StringBuilder sb = new StringBuilder();
                for (Map.Entry<String, BigDecimal> entry : attributeValueTypeMap.entrySet()) {
                    sb.append(entry.getKey()).append("（" + entry.getValue() + "）&nbsp;&nbsp;");
                }
                result.put("attributeValueTypeMap", sb.toString());
            }
            result.put("paperInfoList", paperInfoList);
            // 产品类型
            result.put("printType", paperInfoWrapper.getPrintType());
            // 后工序费用
            result.put("totalCraftPrice", totalCraftPrice);
            // 印刷费用
            result.put("totalPrintPrice", totalPrintPrice);
        }
        // 总价
        result.put("totalTotalPrice", price);
        // 成本价
        result.put("sharePrice", sharePrice);
        // 利润
        result.put("subtract", subtract);
        return result;
    }

    @Override
    public R orderItemProgress(String orderNo) {
        int count = erpOrderAllotRelevanceService.count(new QueryWrapper<ErpOrderAllotRelevanceEntity>()
                .eq("order_allot_no", orderNo)
                .eq("del", DeleteEnum.NOT_DELETE.toInt())
                .isNotNull("crafts_allot_id")
        );
        if (count == 0) {
            return R.error("商品没有制作进度信息");
        }

        return R.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R orderCancel(String orderId) {
        OrderInfoEntity orderInfo = this.baseMapper.selectById(orderId);
        if (!StringUtils.equals(orderInfo.getPayStatus(), PayStatusEnum.PAPER_WAIT_AUDIT_6.toCode())) {
            return R.error("订单已审核");
        }
        if (StringUtils.equals(orderInfo.getPayStatus(), PayStatusEnum.ALREADY_PAY_1.toCode())) {
            return R.error("订单已支付");
        }

        Map<String, Object> updateMap = new HashMap<>();
        updateMap.put("status", OrderInfoStatusEnum.DEAD.toCode());
        this.baseMapper.updateByMap(orderId, updateMap);
        ErpOrderEntity erpOrder = erpOrderService.selectByOrderId(Long.valueOf(orderId));
        String orderNo = erpOrder.getOrderNo();
        updateMap.clear();
        updateMap.put("productionStatus", ProductionStatusEnum.CANCELLED.toInt());
        erpOrderService.updateByMap(updateMap, orderNo);

        ErpOrderAllotRelevanceEntity erpOrderAllotRelevance = erpOrderAllotRelevanceService.getOne(new QueryWrapper<ErpOrderAllotRelevanceEntity>()
                .eq("order_allot_no", orderNo)
                .eq("del", DeleteEnum.NOT_DELETE.toInt())
        );
        Integer oarId = erpOrderAllotRelevance.getOarId();
        updateMap.clear();
        updateMap.put("del", DeleteEnum.DELETE.toInt());
        erpOrderAllotRelevanceService.updateByMap(updateMap, oarId);

        Integer productionId = erpOrderAllotRelevance.getProductionId();
        updateMap.clear();
        updateMap.put("del", DeleteEnum.DELETE.toInt());
        erpOrderProductionService.updateByMap(updateMap, productionId);

        return R.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R orderPay(String orderId) {
        OrderInfoEntity orderInfo = this.baseMapper.selectById(orderId);
        if (StringUtils.equals(orderInfo.getPayStatus(), PayStatusEnum.ALREADY_PAY_1.toCode())) {
            return R.error("订单已支付");
        }

        // 第三发工厂月结
        String payment = "monthAccount";
        String paymentTime = DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
        Map<String, Object> updateMap = new HashMap<>();
        updateMap.put("payStatus", PayStatusEnum.ALREADY_PAY_1.toCode());
        updateMap.put("payed", orderInfo.getPayableAmount());
        updateMap.put("paymentTime", paymentTime);
        updateMap.put("payment", payment);
        this.baseMapper.updateByMap(orderId, updateMap);
        ErpOrderEntity erpOrder = erpOrderService.selectByOrderId(Long.valueOf(orderId));
        String orderNo = erpOrder.getOrderNo();
        erpOrderService.updateByMap(updateMap, orderNo);

        return R.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R orderReceive(String orderId) {
        ErpOrderEntity erpOrder = erpOrderService.selectByOrderId(Long.valueOf(orderId));
        Integer productionStatus = erpOrder.getProductionStatus();
        if (productionStatus.intValue() != ProductionStatusEnum.PRODUCTION_FINISH.toInt()) {
            return R.error("订单未生产完成");
        }

        Map<String, Object> updateMap = new HashMap<>();
        updateMap.put("receivedStatus", ReceivedStatusEnum.RECEIVED.toInt());
        this.baseMapper.updateByMap(orderId, updateMap);
        String orderNo = erpOrder.getOrderNo();
        erpOrderService.updateByMap(updateMap, orderNo);

        erpOrderLogService.insertOrderItemLog(orderNo, null, "工厂订单验货确定");

        return R.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R orderFinish(String orderId) {
        OrderInfoEntity orderInfo = this.baseMapper.selectById(orderId);
        Boolean receivedStatus = orderInfo.getReceivedStatus();
        if (!receivedStatus) {
            return R.error("订单未验货确定");
        }

        String receivedTime = DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
        Map<String, Object> updateMap = new HashMap<>();
        updateMap.put("status", OrderInfoStatusEnum.FINISH.toCode());
        updateMap.put("receivedTime", receivedTime);
        this.baseMapper.updateByMap(orderId, updateMap);
        ErpOrderEntity erpOrder = erpOrderService.selectByOrderId(Long.valueOf(orderId));
        String orderNo = erpOrder.getOrderNo();
        updateMap.clear();
        updateMap.put("receivedTime", receivedTime);
        updateMap.put("productionStatus", ProductionStatusEnum.FINISH.toInt());
        erpOrderService.updateByMap(updateMap, orderNo);

        return R.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R orderDiscount(OrderDiscountDto orderDiscountDto, String username) {
        String orderId = orderDiscountDto.getOrderId();
        OrderInfoEntity orderInfo = this.baseMapper.selectById(orderId);
        String status = orderInfo.getStatus();
        if (StringUtils.equals(status, OrderInfoStatusEnum.FINISH.toCode())) {
            return R.error("订单已审核完成");
        }

        BigDecimal nowDiscount = orderDiscountDto.getDiscount();
        BigDecimal oldDiscount = orderInfo.getDiscount();
        BigDecimal oldPayableAmount = orderInfo.getPayableAmount();
        BigDecimal nowPayableAmount = oldPayableAmount.subtract(oldDiscount).add(nowDiscount);
        int compare = nowPayableAmount.compareTo(BigDecimal.ZERO);
        if (compare < 0) {
            return R.error("应付金额小于0，调价失败");
        }

        Map<String, Object> updateMap = new HashMap<>();
        updateMap.put("discount", nowDiscount);
        updateMap.put("payableAmount", nowPayableAmount);
        this.baseMapper.updateByMap(orderId, updateMap);
        ErpOrderEntity erpOrder = erpOrderService.selectByOrderId(Long.valueOf(orderId));
        if (erpOrder != null){
            erpOrderService.updateByMap(updateMap, orderId);
        }

        ErpOrderAllotRelevanceEntity erpOrderAllotRelevance = erpOrderAllotRelevanceService.getOne(new QueryWrapper<ErpOrderAllotRelevanceEntity>()
                .eq("order_allot_no", orderId)
                .eq("del", DeleteEnum.NOT_DELETE.toInt())
        );
        String originalOrderNo = erpOrderAllotRelevance.getOriginalOrderNo();
        Integer productionId = erpOrderAllotRelevance.getProductionId();

        updateMap.clear();
        updateMap.put("cost", nowPayableAmount);
        erpOrderProductionService.updateByMap(updateMap, productionId);

        String remark = orderDiscountDto.getRemark();
        OrderRemarksEntity orderRemarksEntity = new OrderRemarksEntity();
        orderRemarksEntity.setOrOrderId(Long.valueOf(originalOrderNo));
        orderRemarksEntity.setOrRemarks(remark);
        orderRemarksEntity.setOrCreateName(username);
        orderRemarksService.save(orderRemarksEntity);

        erpOrderLogService.insertOrderItemLog(orderId, null, "工厂订单调价，调价：" + nowDiscount + "，原调价：" + oldDiscount);

        return R.ok();
    }

    @Override
    public R orderYonyou(String orderId, String yonyouOrderNo) {
        ErpOrderEntity erpOrder = erpOrderService.selectByOrderId(Long.valueOf(orderId));
        String orderNo = erpOrder.getOrderNo();
        Map<String, Object> updateMap = new HashMap<>();
        updateMap.put("yonyouOrderNo", yonyouOrderNo);
        erpOrderService.updateByMap(updateMap, orderNo);

        return R.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R produceStart(String orderId) {
        OrderInfoEntity orderInfo = this.getById(orderId);
        // 1.判断是否紫云网或自营门店分配订单，若是则订单无需支付，若是第三方小B，需先支付订单
        // 2.紫云网或自营门店需回写生产操作信息，第三方则不用记录
        List<ErpOrderAllotRelevanceEntity> list = erpOrderAllotRelevanceService.list(new QueryWrapper<>(new ErpOrderAllotRelevanceEntity())
                .eq("order_allot_no", orderId)
                .eq("del", DeleteEnum.NOT_DELETE.toInt())
        );
        if (list.size() == 0){
            return R.error("开始生产失败，不属于第三方分配订单");
        }

        // 订单分配信息
        ErpOrderAllotRelevanceEntity elevanceEntity = list.get(0);
        String originalOrderNo = elevanceEntity.getOriginalOrderNo();
        OrderInfoEntity orderInfoEntity = this.getById(originalOrderNo);
        if (orderInfoEntity == null){
            return R.error("开始生产失败，订单分配信息异常");
        }

        Integer supplierId = orderInfoEntity.getSupplierId();
        SellerInfoEntity sellerInfoEntity = sellerInfoService.getById(supplierId);
        Integer self = sellerInfoEntity.getSelf();
        if (self.intValue() == 0){
            // 非自营第三方
            String payStatus = orderInfo.getPayStatus();
            if (!StringUtils.equals(payStatus, PayStatusEnum.ALREADY_PAY_1.toCode())){
                return R.error("开始生产失败，订单未支付！");
            }
        }else {
            // 生产单号
            Integer productionId = elevanceEntity.getProductionId();
            Map<String, Object> updateMap = new HashMap<>();
            updateMap.put("productionStatus", OrderProductionStatusEnum.PRODUCING.toInt());
            erpOrderProductionService.updateByMap(updateMap, productionId);
        }

        // 修改订单状态
        ErpOrderEntity erpOrder = erpOrderService.getById(orderId);
        if (erpOrder == null) {
            erpOrder = ErpOrderUtils.ziyunOrderToErp(orderInfo);
            erpOrder.setProductionStatus(ProductionStatusEnum.IN_PRODUCTION.toInt());
            erpOrderService.save(erpOrder);
        } else {
            Map<String, Object> updateMap = new HashMap<>();
            updateMap.put("productionStatus", ProductionStatusEnum.IN_PRODUCTION.toInt());
            erpOrderService.updateByMap(updateMap, orderId);
        }

        erpOrderLogService.insertOrderItemLog(orderId, null, "订单开始生产");

        return R.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R produceFinish(String orderId) {
        OrderInfoEntity orderInfo = this.getById(orderId);
        // 1.判断是否紫云网或自营门店分配订单，若是则订单无需支付，若是第三方小B，需先支付订单
        // 2.紫云网或自营门店需回写生产操作信息，第三方则不用记录
        List<ErpOrderAllotRelevanceEntity> list = erpOrderAllotRelevanceService.list(new QueryWrapper<>(new ErpOrderAllotRelevanceEntity())
                .eq("order_allot_no", orderId)
                .eq("del", DeleteEnum.NOT_DELETE.toInt())
        );
        if (list.size() == 0){
            return R.error("生产完成失败，不属于第三方分配订单");
        }
        // 订单分配信息
        ErpOrderAllotRelevanceEntity elevanceEntity = list.get(0);
        // 原始订单号
        String originalOrderNo = elevanceEntity.getOriginalOrderNo();
        OrderInfoEntity orderInfoEntity = this.getById(originalOrderNo);
        Integer supplierId = orderInfoEntity.getSupplierId();
        SellerInfoEntity sellerInfoEntity = sellerInfoService.getById(supplierId);
        Integer self = sellerInfoEntity.getSelf();
        if (self.intValue() == 1){
            // 生产单号
            Integer productionId = elevanceEntity.getProductionId();
            Map<String, Object> updateMap = new HashMap<>();
            updateMap.put("productionStatus", OrderProductionStatusEnum.FINISH.toInt());
            erpOrderProductionService.updateByMap(updateMap, productionId);
        }

        Map<String, Object> updateMap = new HashMap<>();
        updateMap.put("productionStatus", ProductionStatusEnum.PRODUCTION_FINISH.toInt());
        updateMap.put("finishTime", DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
        erpOrderService.updateByMap(updateMap, orderId);

        erpOrderLogService.insertOrderItemLog(orderId, null, "订单生产完成");

        return R.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R confirmGetGoods(String orderId) {
        String receivedTime = DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
        Map<String, Object> updateMap = new HashMap<>();
        updateMap.put("status", OrderInfoStatusEnum.FINISH.toCode());
        updateMap.put("receivedStatus", ReceivedStatusEnum.RECEIVED.toInt());
        updateMap.put("receivedTime", receivedTime);
        this.baseMapper.updateByMap(orderId, updateMap);

        updateMap.remove("status");
        updateMap.put("productionStatus", ProductionStatusEnum.FINISH.toInt());
        erpOrderService.updateByMap(updateMap, orderId);

        return R.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R confirmReceive(String orderId) {
        OrderInfoEntity orderInfo = this.getById(orderId);
        Boolean receivedStatus = orderInfo.getReceivedStatus();
        if (receivedStatus){
            return R.error("订单已验货确定");
        }

        // 查询生产单信息
        ErpOrderProductionEntity erpOrderProduction = new ErpOrderProductionEntity();
        ErpOrderProductionEntity erpOrderProductionEntity = erpOrderProductionService.getOne(new QueryWrapper<>(erpOrderProduction).eq("production_order", orderId));
        String orderNo = erpOrderProductionEntity.getOrderNo();
        String orderItemId = erpOrderProductionEntity.getOrderItemId();
        String erpItemId = erpOrderProductionEntity.getErpItemId();

        // 商品状态改为生产完成
        Map<String, Object> updateMap = new HashMap<>();
        updateMap.put("status", OrderItemStatusEnum.PRODUCTION_FINISH.toInt());
        erpOrderItemService.updateByMap(updateMap, Integer.valueOf(erpItemId));

        // 分配订单已收货
        updateMap.clear();
        updateMap.put("receivedStatus", ReceivedStatusEnum.RECEIVED.toInt());
        this.baseMapper.updateByMap(orderId, updateMap);
        erpOrderService.updateByMap(updateMap, orderId);

        erpOrderLogService.insertOrderItemLog(orderNo, Long.valueOf(orderItemId), "工厂订单验货确定");

        return R.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R auditFinish(String orderId) {
        OrderInfoEntity orderInfo = this.getById(orderId);
        String status = orderInfo.getStatus();
        if (status.equals(OrderInfoStatusEnum.FINISH.toCode())){
            return R.error("订单已完结");
        }

        // 查询生产单信息
        ErpOrderProductionEntity erpOrderProduction = new ErpOrderProductionEntity();
        ErpOrderProductionEntity erpOrderProductionEntity = erpOrderProductionService.getOne(new QueryWrapper<>(erpOrderProduction).eq("production_order", orderId));
        Integer productionId = erpOrderProductionEntity.getProductionId();

        // 修改生产单财务审核为待付款
        Map<String, Object> updateMap = new HashMap<>();
        updateMap.put("financeStatus", FinanceStatusEnum.UN_PAYD.toInt());
        updateMap.put("cost", orderInfo.getPayableAmount());
        erpOrderProductionService.updateByMap(updateMap, productionId);

        String receivedTime = DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
        updateMap.clear();
        updateMap.put("status", OrderInfoStatusEnum.FINISH.toCode());
        updateMap.put("receivedStatus", 1);
        updateMap.put("receivedTime", receivedTime);
        updateMap.put("payed", orderInfo.getPayableAmount());// 已支付金额
        updateMap.put("payStatus", PayStatusEnum.ALREADY_PAY_1.toCode()); // 支付状态
        updateMap.put("payment", "monthAccount"); // 支付方式
        updateMap.put("paymentTime", receivedTime); // 支付时间
        this.baseMapper.updateByMap(orderId, updateMap);

        updateMap.remove("status");
        updateMap.put("productionStatus", ProductionStatusEnum.FINISH.toInt());
        erpOrderService.updateByMap(updateMap, orderId);
        return R.ok();
    }

    /**
     * 小b分配工厂订单联动支付
     *
     * @param payParamDto
     * @param mallUserId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R orderPayUmf(PayParamDto payParamDto, Long mallUserId, String ip) {
        String orderId = payParamDto.getOrderId();
        PayType payType = payParamDto.getPayType();
        // 回调地址
        payParamDto.setReturnUrl(mfSyncCallbackuUrl);

        if (orderId == null || payType == null) {
            throw new RRException(ResultCode.PARAM_LESS);
        }
        // 检查订单是否支付过
        this.checkOrderIsPay(orderId);

        // 待支付金额
        BigDecimal surplusPayed = this.getOrderPayed(orderId, mallUserId);

        // 支付数据
        Map<String, Object> rs = this.getOrderUmfPay(payParamDto, surplusPayed, mallUserId, ip);


        return R.ok(rs);
    }

    /**
     * 联动支付异步回调 处理状态
     *
     * @param request
     * @param response
     */
    @Override
    public void umfPayRecall(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String requestParam = request.getQueryString();

        if (org.apache.commons.lang.StringUtils.isEmpty(requestParam)) {
            _log.error("recall params is  [{}] ", requestParam);
            throw new PayException(com.service.common.protocol.ResultCode.PARAM_ERROR);
        }

        // 获得返回dto
        Map<String, Object> returnMap = analyzeParam(requestParam);
        System.out.println("支付回调信息：" + returnMap.toString());
        String resMetaData = umfPayConfig.getUmfService().responseUMFMap(returnMap);
        PayRecallResult payRecallResult = new PayRecallResult();
        BeanMapUtil.mapToBean(returnMap, payRecallResult);
        payRecallResult.setResMetaData(resMetaData);
        String mer_priv = payRecallResult.getMer_priv();
        String payUse = org.apache.commons.lang.StringUtils.EMPTY;
        if (mer_priv.contains("order")) {
            payUse = "order";
        }

        String paymentId = payRecallResult.getOrder_id(); // 商城支付单号
        String trade_no = payRecallResult.getTrade_no(); // 微信单号
        String trade_state = payRecallResult.getTrade_state();
        PayTradeStateCode tradeStateCode = PayTradeStateCode.valueOf(trade_state);
        BigDecimal money = new BigDecimal(payRecallResult.getAmount()).divide(BigDecimal.valueOf(100));// 金额

        PayStatus payStatus = null;
        switch (tradeStateCode) {
            // 交易成功
            case TRADE_SUCCESS:
                payStatus = PayStatus.succ;
                break;
            // 交易关闭
            case TRADE_CLOSED:
                payStatus = PayStatus.timeout;
                break;
            // 交易撤销
            case TRADE_CANCEL:
                payStatus = PayStatus.cancel;
                break;
            // 交易失败
            case TRADE_FAIL:
                payStatus = PayStatus.failed;
                break;
            default:
                _log.error("联动支付回调失败,无对应支付状态,接收报文：" + com.utility.JsonUtils.object2String(returnMap));
                return;
        }
        if (payStatus != PayStatus.succ) {
            return;
        }

        // 交易状态
        Boolean flag = false;

        flag = this.checkAndUpPayment(paymentId, trade_no, money, PayType.umfbankpay,  payStatus);


        if (flag) {
            response.setContentType("text/html;charset=utf-8");
            try {
                PrintWriter out = response.getWriter();
                out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
                out.println("<HTML>");
                out.println(" <HEAD><META NAME=\"MobilePayPlatform\" CONTENT=\"" + payRecallResult.getResMetaData()
                        + "\" /></HEAD>");
                out.println(" <BODY>");
                out.print(" This is ");
                out.print(this.getClass());
                out.println(", using the GET method");
                out.println("</BODY>");
                out.println("</HTML>");
                out.flush();
                out.close();
            } catch (IOException e) {
                _log.error("联动支付回调失败,接收报文：" + com.utility.JsonUtils.object2String(returnMap));
                e.printStackTrace();
            }
        }
    }

    private Boolean checkAndUpPayment(String paymentId, String trade_no, BigDecimal money, PayType payType, PayStatus payStatus) throws Exception {
        UserPaymentEntity userPayment = this.userPaymentService.getById(paymentId);
        if (userPayment == null) {
            _log.error(payType.toString() + "支付回调失败,查询不到对应的支付流水,接收报文：" + com.utility.JsonUtils.object2String(paymentId));
            // error("支付宝支付回调失败,支付金额不一致,接收报文：" + JsonUtils.object2String(payResult));
            return false;
        }

        // 状态比对
        if (PayStatus.succ.toString().equals(userPayment.getStatus())) {
            // 状态比对不一致
            _log.error(payType.toString() + "支付回调失败,支付流水状态为成功,接收报文：" + com.utility.JsonUtils.object2String(userPayment));
            // error("支付宝支付回调失败,支付金额不一致,接收报文：" + JsonUtils.object2String(payResult));
            return false;
        }

        // 比对金额
        BigDecimal scMoney = userPayment.getMoney();// 商城金额
        if (scMoney.compareTo(money) != 0) {
            // 支付金额不一致
            _log.error(payType.toString() + "支付回调失败,支付金额不一致,接收报文：" + com.utility.JsonUtils.object2String(userPayment));
            // error("支付宝支付回调失败,支付金额不一致,接收报文：" + JsonUtils.object2String(payResult));
            return false;
        }

        // 查询单号对应的订单号
        String parentOrderId =  this.userPaymentBillService.getOrderByBillId(paymentId);
        if (com.utility.StringUtils.isBlank(parentOrderId)) {
            _log.error(payType.toString() + "支付回调失败,查不到对应的订单号,接收报文：" + com.utility.JsonUtils.object2String(userPayment));
            // error("支付宝支付回调失败,查不到对应的订单号,接收报文：" + JsonUtils.object2String(payResult));
            return false;
        }

        UserPaymentLogDto paymentLogDto = UserPaymentLogDto.valueOfPayCallback(paymentId, scMoney,
                PayType.valueOf(userPayment.getPayAppId()), PayUse.order, trade_no, parentOrderId, payStatus);

        // 处理支付流水、订单状态
        this.updatePaymentBill(paymentLogDto);

        return true;
    }
    // 更新支付流水状态
    @Transactional(rollbackFor = Exception.class)
    public void updatePaymentBill(UserPaymentLogDto paymentLogDto) throws Exception {

        // 更新支付记录
        UserPaymentEntity userPayment = new UserPaymentEntity();
        userPayment.setPaymentId(paymentLogDto.getPaymentId());
        userPayment.setTradeNo(paymentLogDto.getTradeNo());
        userPayment.setStatus(paymentLogDto.getPayStatus().name());
        // 更新三方支付流水信息
        this.userPaymentService.updateById(userPayment);

        // 处理订单状态
        if (paymentLogDto.getPayStatus() == PayStatus.succ) {
            this.savePayInfo(paymentLogDto, OrderPayStatus.payed);
        }
    }

    /**
     * 订单处理
     * @param paymentLogDto
     * @param payStatus
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    public void savePayInfo(UserPaymentLogDto paymentLogDto, OrderPayStatus payStatus) throws Exception {

        String orderId = paymentLogDto.getRelId();// 订单号
        String paymentId = paymentLogDto.getPaymentId();// 支付id
        BigDecimal orderAmount = paymentLogDto.getMoney();// 订单剩余支付金额
        // String tradeNo = paymentLogDto.getTradeNo();// 外部单号
        PayType payWay = paymentLogDto.getPayWay();

        // 修改父订单状态 小b 不存在
       /* OrderParentInfo orderParentInfo = OrderParentInfoDao.instance.selectById(orderId);
        if (orderParentInfo != null) {
            OrderParentInfo updateOrderParentInfo = OrderParentInfo.builder().build();
            updateOrderParentInfo.setParentOrderId(orderId);
            updateOrderParentInfo.setStatus(OrderStatusChangeEvent.payed.getOrderStatus());
            updateOrderParentInfo.setPayStatus(payStatus.getPayStatus());
            BigDecimal payed = orderParentInfo.getPayed().add(orderAmount);
            updateOrderParentInfo.setPayed(payed);
            OrderParentInfoDao.instance.updateSelectiveById(updateOrderParentInfo);
        }*/

        // 修改子订单状态
        //根据订单查找子订单信息
        QueryWrapper<OrderInfoEntity> queryWrapper = new QueryWrapper<OrderInfoEntity>();
        queryWrapper.eq("parent_order_id", orderId).or().eq("order_id", orderId);
        queryWrapper.orderByAsc("payable_amount");

        List<OrderInfoEntity> orderInfoList = this.orderInfoService.list(queryWrapper);
        int orderSize = orderInfoList.size();
        List<OrderInfoEntity> updateOrderList = New.arrayList(orderSize);
        List<OrderLogEntity> orderLogList = New.arrayList(orderSize);
        List<OrderPaymentEntity> orderPaymentList = New.arrayList(orderSize);
        Integer userId = null;
        Set<String> orderIds = New.hashSet(orderSize);
        String pickUpOrderIds = org.apache.commons.lang.StringUtils.EMPTY;
        String pickUpCode = org.apache.commons.lang.StringUtils.EMPTY;
        String shipMobile = org.apache.commons.lang.StringUtils.EMPTY;
        Long factoryId = null;
        for (OrderInfoEntity orderInfo : orderInfoList) {
            factoryId = Long.valueOf(orderInfo.getFactoryId().toString()) ;
            userId = orderInfo.getUserId();
            if ("3".equals(orderInfo.getPayStatus()) || "0".equals(orderInfo.getPayStatus())) {
                orderIds.add(orderInfo.getOrderId());
                OrderInfoEntity updateOrder = new OrderInfoEntity();
                updateOrder.setOrderId(orderInfo.getOrderId());
                updateOrder.setPayStatus(payStatus.getPayStatus());
                updateOrder.setStatus(OrderStatusChangeEvent.payed.getOrderStatus());
                // 还需支付金额
                BigDecimal orderSurplusPayed = orderInfo.getPayableAmount().subtract(orderInfo.getPayed());
                updateOrder.setPayed(orderInfo.getPayed().add(orderSurplusPayed));
                // 剩余金额
                BigDecimal surplusPayed = orderAmount.subtract(orderSurplusPayed);

                // 订单支付日志
                OrderLogEntity log = new OrderLogEntity();
                log.setOpId(userId);
                log.setOrderId(orderInfo.getOrderId());
                log.setBehavior("payments");
                log.setResult("SUCCESS");
                log.setLogText("买家已经付款，订单" + orderId + "," + payWay.getPayType() + "付款" + orderAmount + "元");

                // 订单支付记录表
                OrderPaymentEntity orderPayment = new OrderPaymentEntity();
                orderPayment.setOrderId(orderInfo.getOrderId());
                orderPayment.setPaymentId(paymentId);
                orderPayment.setMoney(orderSurplusPayed);

                // 付款金额完了
                if (surplusPayed.compareTo(BigDecimal.ZERO) == -1) {
                    updateOrder.setPayStatus(OrderPayStatus.otherPay.getPayStatus());
                    updateOrder.setPayed(orderInfo.getPayed().add(orderAmount));
                    orderPayment.setMoney(orderAmount);
                    log.setLogText("买家已经付款，订单" + orderInfo.getOrderId() + "," + payWay.getPayType() + "付款"
                            + orderInfo.getPayed().add(orderAmount) + "元");
                }
                if ("1".equals(updateOrder.getPayStatus()) && orderInfo.getPickUp()
                        && org.apache.commons.lang.StringUtils.isNotBlank(orderInfo.getPickUpCode())) {
                    pickUpOrderIds += orderInfo.getOrderId() + " ";
                    pickUpCode = orderInfo.getPickUpCode();
                    if (org.apache.commons.lang.StringUtils.isNotEmpty(orderInfo.getShipMobile())
                            && ParamValidator.isPhone(orderInfo.getShipMobile())) {
                        shipMobile = orderInfo.getShipMobile();
                    }
                }
                updateOrderList.add(updateOrder);
                orderLogList.add(log);
                orderPaymentList.add(orderPayment);

                if (surplusPayed.compareTo(BigDecimal.ZERO) != 1) {
                    break;
                }
                orderAmount = surplusPayed;

            }
        }
        this.orderInfoService.updateBatchById(updateOrderList);

        // 修改设计信息表状态 小b分配订单无设计订单
        //OrderDesignInfoDao.instance.updateStatusByOrderIds(orderIds);

        // 保存日志信息
        this.orderLogService.saveBatch(orderLogList);
        // 订单支付记录
        this.paymentService.saveBatch(orderPaymentList);

        /** 发送自提短信 */
        // if (StringUtils.isNotBlank(pickUpOrderIds) &&
        // StringUtils.isNotBlank(pickUpCode)
        // && StringUtils.isNotBlank(shipMobile)) {
        // BaseResult<?> ucenterResult = ucenterService.getOrderPickUpCode(shipMobile,
        // pickUpOrderIds, pickUpCode);
        // if (ucenterResult == null || ucenterResult.getCode() !=
        // ResultCode.SUCCESS.getCode()) {
        // _log.error("订单：" + pickUpOrderIds + ",发送提货码失败,param[" + shipMobile + "," +
        // pickUpCode + "]");
        // error("订单：" + pickUpOrderIds + ",发送提货码失败,param[" + shipMobile + "," +
        // pickUpCode + "]");
        // }
        // }
        //
        // // 订单推送
        // if (factoryId != null) {
        // PushParamVo pushParamVo = PushParamVo.valueOf(PushType.PAY_ORDER, factoryId,
        // orderInfo.getOrderId());
        // pushService.pushOrderMsg(pushParamVo);
        // }
    }

    /**
     * 准备支付数据
     *
     * @param payParamDto
     * @param surplusPayed
     * @return
     */
    private Map<String, Object> getOrderUmfPay(PayParamDto payParamDto, BigDecimal surplusPayed, Long mallUserId, String ip) {
        String orderId = payParamDto.getOrderId();

        // 查询是否有原有单号
        Map<String, String> orderPayment = New.hashMap();

        orderPayment = this.userPaymentService.getPaymentById(orderId, payParamDto.getPayType().toString(), surplusPayed);

        String paymentId = StringUtils.EMPTY;
        String paymentDate = StringUtils.EMPTY;
        if (MapUtils.isEmpty(orderPayment)) {
            paymentId = NumberUtil.getPaymentsId();
            paymentDate = com.utility.DateUtils.getPaymentDateStr();
        } else {
            paymentId = orderPayment.get("paymentId");
            paymentDate = orderPayment.get("paymentDate");
            String recode = this.checkUmfPayment(paymentId, paymentDate);
            // 订单已过期
            if (com.utility.StringUtils.isNotBlank(recode) && recode.equals("00200080")) {
                this.updatePaymentError(paymentId);
                paymentId = NumberUtil.getPaymentsId();
                paymentDate = com.utility.DateUtils.getPaymentDateStr();
                orderPayment = null;
            }
        }

        UserPaymentLogDto paymentLogDto = new UserPaymentLogDto();
        paymentLogDto.setMoney(surplusPayed);
        paymentLogDto.setPaymentId(paymentId);
        paymentLogDto.setPayUse(PayUse.order);
     /*   paymentLogDto.setPayWay(payParamDto.getPayType());
        paymentLogDto.setRelId(mallUserId.toString());*/

        Map<String, Object> umfPay = this.getUmfPay(paymentLogDto, payParamDto.getReturnUrl(), payParamDto.getPayType(), orderId, paymentDate,
                payParamDto.getBankCode(), mallUserId, ip);
        if (MapUtils.isEmpty(orderPayment)) {
            // 保存支付记录
            paymentLogDto.setPayWay(payParamDto.getPayType());
            paymentLogDto.setRelId(orderId);
            this.insertPeyment(paymentLogDto,mallUserId, ip);
        } else {
            // 修改支付记录渠道
            updatePaymentSource(orderPayment.get("paymentId"));
        }

        return umfPay;

    }
    /***
     * 修改支付渠道
     *
     * @param orderPaymentId
     */
    @Transactional(rollbackFor = Exception.class)
    public void updatePaymentSource(String orderPaymentId)  {

        // 修改支付记录渠道
        UserPaymentEntity userPayment = new UserPaymentEntity();
        userPayment.setPaymentId(orderPaymentId);
        userPayment.setSource("erp");
        this.userPaymentService.updateById(userPayment);
    }

    /**
     * 支付记录表 支付对账表
     *
     * @param paymentLogDto
     * @param userId
     * @param ip
     * @throws RRException
     */
    @Transactional(rollbackFor = Exception.class)
    public void insertPeyment(UserPaymentLogDto paymentLogDto, Long userId, String ip) throws RRException {

        AppType appType = AppType.valueOf("erp");
        // 支付方式
        PayType payWay = paymentLogDto.getPayWay();
        UserPaymentEntity paymentLog = new UserPaymentEntity();
        //BeanUtils.copyProperties(paymentLogDto, paymentLog);
        paymentLog.setPaymentId(paymentLogDto.getPaymentId());
        paymentLog.setIp(ip);
        paymentLog.setMoney(paymentLogDto.getMoney());
        paymentLog.setUserId(String.valueOf(userId));
        paymentLog.setPayName(payWay.getPayType());
        paymentLog.setPayAppId(payWay.toString());
        paymentLog.setSource(appType.getTypeName());

        // 保存订单或充值与支付关系表

        UserPaymentBillEntity paymentBill = new UserPaymentBillEntity();
        paymentBill.setRelId(Long.parseLong(paymentLogDto.getRelId()));
        paymentBill.setMoney(paymentLogDto.getMoney());
        paymentBill.setPayObject(paymentLogDto.getPayUse().toString());
        paymentBill.setBillId(paymentLogDto.getPaymentId());

        // 其余字段
        // 回调时候写
        this.userPaymentService.save(paymentLog);
        this.userPaymentBillService.save(paymentBill);
    }

    private Map<String, Object> getUmfPay(UserPaymentLogDto paymentLogDto, String returnUrl, PayType payType, String orderId, String paymentDate,
                                          BankCode bankCode, Long mallUserId, String userIp) {
        String paymentId = paymentLogDto.getPaymentId();
        BigDecimal surplusPayed = paymentLogDto.getMoney();
        PayUse payUse = paymentLogDto.getPayUse();
        String notifyUrl = callbackConfig.getUmfPayCallbackUrl();

        String priv = payUse.toString();
        if (com.utility.StringUtils.isNotBlank(orderId)) {
            priv += Splitable.COMMA + orderId;
        }
        String privStr;
        try {
            privStr = new String(priv.getBytes(), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            _log.error(e.getMessage());
            throw new RRException(ResultCode.PAYMENT_ERROR);
        }

        String pcReturnUrl = com.utility.StringUtils.EMPTY;
        // 此处只处理联动  umfalipay umfweixinpay umfupacppay
        WebPayParam webPayParam = WebPayParam.valueOf(paymentId, surplusPayed, payUse.getPayUse(), returnUrl,
                notifyUrl, paymentDate, mallUserId, userIp, privStr);
        if (payType == PayType.umfalipay || payType == PayType.umfweixinpay) {
            webPayParam.setPayment_mode(payType.getPayCode());
        } else {
            // webPayParam.setPay_type("B2CBANK");
        }
        pcReturnUrl = umfPayService.webpay(webPayParam);

        Map<String, Object> payUrl = New.hashMap(1);
        payUrl.put("payUrl", pcReturnUrl);
        payUrl.put("payType", payType.toString());

        return payUrl;
    }

    @Transactional(rollbackFor = Exception.class)
    public void updatePaymentError(String orderPaymentId) {
        UserPaymentEntity userPayment = new UserPaymentEntity();
        userPayment.setPaymentId(orderPaymentId);
        userPayment.setStatus("timeout");
        this.userPaymentService.updateById(userPayment);
    }

    /***
     * 联动
     * 检查支付号是否已经支付
     *
     * @param paymentId
     * @param paymentDate
     */
    private String checkUmfPayment(String paymentId, String paymentDate) {
        QueryPayParam queryPay = QueryPayParam.valueOf(paymentId, paymentDate);
        BaseResult<QueryPayResult> baseResult = umfPayService.queryPay(queryPay);
        QueryPayResult payResult = baseResult.getData();
        if (payResult.getRet_code().equals("0000") && payResult.getTrade_state().equals("TRADE_SUCCESS")) {
            // 订单已支付
            throw new RRException(ResultCode.PAYMENT_SUCCESS);
        } else if (payResult.getRet_code().equals("00060780")) {
            // 订单已支付
            throw new RRException(ResultCode.PAYMENT_SUCCESS);
        } else if (payResult.getRet_code().equals("00200014") || payResult.getRet_code().equals("00060761")
                || payResult.getRet_code().equals("00080730")) {
            // 支付中 情况未明
            throw new RRException(ResultCode.PAYMENT_MIDDLE);
        } else if (payResult.getRet_code().equals("00200078") || payResult.getRet_code().equals("00200080")) {
            // 订单不存在 订单已关闭
            return payResult.getRet_code();
        } else if (!payResult.getRet_code().equals("0000")) {
            _log.error("支付查单失败，返回码 [{}],返回信息 [{}]", payResult.getRet_code(), payResult.getRet_msg());
            throw new RRException(ResultCode.PAYMENT_ERROR);
        } else if (payResult.getRet_code().equals("0000") && !payResult.getTrade_state().equals("WAIT_BUYER_PAY")) {
            _log.error("支付查单失败，返回码 [{}],返回信息 [{}],返回状态 [{}]", payResult.getRet_code(), payResult.getRet_msg(),
                    payResult.getTrade_state());
            throw new RRException(ResultCode.PAYMENT_ERROR);
        }
        return null;
    }

    /**
     * 订单待支付金额
     *
     * @param orderId
     * @param mallUserId
     * @return
     */
    private BigDecimal getOrderPayed(String orderId, Long mallUserId) {
        BigDecimal surplusPayed = BigDecimal.ZERO;

        //根据订单查找子订单信息
        QueryWrapper<OrderInfoEntity> queryWrapper = new QueryWrapper<OrderInfoEntity>();
        queryWrapper.eq("parent_order_id", orderId).or().eq("order_id", orderId);
        if (mallUserId != null) {
            queryWrapper.eq("status", "active").eq("user_id", mallUserId);
        }
        queryWrapper.orderByAsc("payable_amount");

        List<OrderInfoEntity> orderInfoList = this.orderInfoService.list(queryWrapper);
        if (CollectionUtils.isEmpty(orderInfoList)) {
            throw new RRException(ResultCode.ORDER_STATUS_CHANGE);
        }
        for (OrderInfoEntity orderInfo : orderInfoList) {
            if (orderInfo.getPayStatus().equals("0") || orderInfo.getPayStatus().equals("3")) {
                surplusPayed = surplusPayed.add(orderInfo.getPayableAmount().subtract(orderInfo.getPayed()));
            }
        }
        if (surplusPayed.compareTo(BigDecimal.ZERO) != 1) {
            throw new RRException(ResultCode.ORDER_STATUS_CHANGE);
        }
        surplusPayed = NumberUtil.getRoundDown(surplusPayed);
        if (surplusPayed.compareTo(BigDecimal.ZERO) != 1) {
            throw new RRException(ResultCode.ORDER_STATUS_CHANGE);
        }
        return surplusPayed;

    }

    /***
     * 检查订单是否已经支付过
     *
     * @param orderId
     */
    private void checkOrderIsPay(String orderId) {
        Integer isPay = this.userPaymentService.checkOrderIsPay(orderId);
        if (isPay != null & isPay.intValue() > 0) {
            throw new RRException(ResultCode.ORDER_PAY);
        }
    }

    /**
     * 解析参数
     *
     * @author 丁烽
     * @version 创建时间：2018年5月23日 上午11:23:12
     */
    @SuppressWarnings("unchecked")
    public Map<String, Object> analyzeParam(String requestParam) throws Exception {

        Map<String, Object> respMap = umfPayConfig.getUmfService().notifyDataParserMap(requestParam);
        return respMap;
    }

}
